perm filename XAP1.NEW[XAP,BGB] blob
sn#058609 filedate 1973-08-22 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00015 PAGES
C REC PAGE DESCRIPTION
C00001 00001 VALID 00015 PAGES
C00003 00002 TITLE XAP - XEROX ASSEMBLE AND PRINT - BGB - 27 JANUARY 1973.
C00007 00003 FONT SPECIFICATION.
C00008 00004 XGP RASTER PAGE BUFFER.
C00010 00005 ALTERNATE PDP-10 MNEMONICS.
C00015 00006 START ADDRESS ENTRY.
C00017 00007 SUBR(BEGPROG) BEGIN PROGRAM.
C00019 00008 SUBR(PASS1)
C00020 00009 SUBR(PASS2)
C00023 00010 HTAB: LAC COL↔SUB LMAR TEXT HORIZONTAL TAB.
C00024 00011 SUBR(MKTABL) MAKE 2D BIT ADDRESSING TABLE IN 2ND SEGMENT.
C00028 00012 SUBR(XGPOUT) OUTPUT BUFFER TO XGP FROM SECONDARY STORAGE.
C00031 00013 SUBR(PRINT) PLACE A GLYPH INTO XGP BUFFER AT ROW,COL.
C00034 00014 SUBR TEXT
C00041 00015 SUBR LBLINE
C00046 ENDMK
C⊗;
TITLE XAP - XEROX ASSEMBLE AND PRINT - BGB - 27 JANUARY 1973.
;JOB DATA AREA AND CORE MAP.
PDL: BLOCK 100 ;CONTROL PUSH DOWN.
PDLLEN←←.-PDL
PAT: BLOCK 100 ;PATCH AREA.
LINBUF: BLOCK 100 ;Line buffer for justification
LINLEN←←.-LINBUF
EXTERN JOBJDA ;140 END OF JOB DATA AREA.
EXTERN JOBFF ;121 TOP OF USED CORE POINTER.
EXTERN JOBSA ;120 XWD ORGINAL-TOP,START-ADDR.
EXTERN JOBREL ; 44 PHYSICAL TOP OF CORE IMAGE.
;PROCESSOR STATUS.
PASS:0 ;0 FOR PASS1, -1 FOR PASS2.
PMODE:0 ;PAGINATION MODE: 0 MANUAL, -1 AUTOMATIC.
WFMODE:0 ;WINDOW FILLING MODE: 0 TEXT, -1 GRAPHICS, +1 XGP.
CMODE:0 ;-1 COMMAND MODE. 0 TEXT MODE.
CHAR:0 ;CURRENT CHARACTER.
CHRCNT:0 ;CHARACTERS REMAINING.
TXTPTR:0 ;TEXT POINTER.
TXTORG:0 ;TEXT ORIGIN.
TXTEND:0
XLINE:2 ;EXTRA LINES BETWEEN ROWS OF CHARACTERS
EOF:0↔HIDDEN:0
BUGFLG:-1;0 ;-1 WHEN DEBUGGING.
;DSK I/O DATA AREA.
FILNAM: 0 ;FILE NAME.
EXTION: 0↔0 ;EXTENSION.
PPPN: 0↔0 ;PROJECT-PROGRAMMER.
RPGFLG: 0
;TEXT JUSTFICATION MODES:
$AUTOCR←←-1
$CLIP←← 0
$BOTH←← 1
$RIGHT←← 2
$CENTER←← 3
$LEFT←← 4
TJMODE: 1;(THE HARD ONE) ;Current text justification mode
TJPTR: BLOCK 1 ;Byte pointer to end of buffer-1.
TJCNT: BLOCK 1 ;Number of characters remaining in buffer.
TJHEIGHT: BLOCK 1 ;Maximum height.
TJDEPTH: BLOCK 1 ;Maximum depth.
TJODEPTH: BLOCK 1 ;Old maximum depth.
TJFONT: BLOCK 1 ;Last font selected when TEXT was called.
TJSPTR: BLOCK 1 ;Pointer to last space in line buffer.
TJSCNT: BLOCK 1 ;Number of spaces in line buffer.
TJSPOS: BLOCK 1 ;Column where last space begins
TJLMAR: BLOCK 1 ;Left margin for text justification.
TJRMAR: BLOCK 1 ;Right margin for text justification.
LFFLAG: BLOCK 1 ;Line feed has been seen but not processed.
CRFLAG: BLOCK 1 ;Return has been seen but not processed.
SAVTPC: BLOCK 1 ;For the quarter page kludge
;FONT SPECIFICATION.
FONT: 1
FONTAB: BLOCK =45
FNTPPN: SIXBIT/XGPSYS/ ;DEFAULT FONT PPN
FNTNAM: 0 ;DEFAULT FONT NAMES.
SIXBIT/LPT/ ;1 LINE PRINTER.
SIXBIT/FIX13X/ ;2 FIXED WIDTH FONTS.
SIXBIT/FIX20/ ;3
SIXBIT/FIX25/ ;4
SIXBIT/FIX40/ ;5
SIXBIT/NGR13/ ;6 NEW GOTHIC ROMAN.
SIXBIT/NGR20/ ;7
SIXBIT/NGR25/ ;8
SIXBIT/NGR30/ ;9
SIXBIT/NGR40/ ;A
SIXBIT/BDR25/ ;B BODONI ROMAN
SIXBIT/BDI25/ ;C BODONI ITALIC
SIXBIT/BDR40/ ;D
SIXBIT/XMAS25/ ;E PSEUDO OLDE ENGLISH.
SIXBIT/SIGN57/ ;F
SIXBIT/GRK25/ ;G GREEK.
SIXBIT/SET1/ ;H TOVAR'S CREATION.
;XGP RASTER PAGE BUFFER.
ROW:0 ;XGP "PEN" POSITION.
COL:0
DROW:0 ;DELTA PEN POSITION FOR LINE FEED AND SPACE.
DCOL:0
QPAGE:0 ;QUARTER PAGE: 0, 1, 2, 3.
QLO:0↔QHI:0 ;QUARTER ROW LOW & QUARTER ROW HI.
ORGXGP:0 ;XGP BUFFER (1/4 OF A PAGE).
ENDXGP:0
;XGP RASTER DIMENSIONS.
WWIDTH←←=49 ;WORD WIDTH OF A ROW.
NCOLS←←(WWIDTH-1)*=36 ;NUMBER OF COLUMNS IS 1728.
MROWS←←=2048 ;NUMBER OF ROWS IS 2048.
BUFSIZ←←WWIDTH*MROWS/4 ;SIZE OF XGP BUFFER (ONE QUARTER PAGE).
;III BUFFER DISPLAY.
IIIDX: =1024
IIIDY: =1024
ROTDEL:0
SINE:0↔COSINE:1.0 ;ORIENTATION.
SCALEX:1.0↔SCALEY:1.0 ;DILATION.
;TEXT JUSTIFICATION PARAMETERS.
RMAR:NCOLS
LMAR:=200
ROWMIN:=200
ROWMAX:MROWS
;GRAPHICS WINDOW.
GWROWS:0 ;RASTER SIZE.
GWCOLS:0
GWROW0:0 ;RASTER ORIGIN.
GWCOL0:0
;ALTERNATE PDP-10 MNEMONICS.
DEFINE O(A,B){OPDEF A[B]}
O LIP,HLR↔O LAP,HRR↔O DIP,HRLM↔O DAP,HRRM
O ZIP,HRRZS↔O ZAP,HLLZS↔O WIP,HRROS↔O WAP,HRRZS
O CAR,HLRZ↔O LIPI,HRLI↔O LAPI,HRRI↔O DIPZ,HRLZM
O CDR,HRRZ↔O LACI,MOVEI↔O SLACI,MOVSI↔O DAPZ,HRRZM
O LAC,MOVE↔O LACN,MOVN↔O LACM,MOVM↔O SLAC,MOVS
O DAC,MOVEM↔O DACN,MOVNM↔O DACM,MOVMM↔O SDAC,MOVSM
O NIP,HLRE↔O NAP,HRRE↔O NIM,HRREI↔O GO,JRST
O FLOAT,FSC 233↔O FIXX,FIX 233000↔O DZM,SETZM
;SAIL LIKE SUBROUTINE LINKAGE.
↓P←←17
DEFINE SUBR(NAME){INTERN NAME↔↓NAME: ;}
; DEFINE CALL(NAME,X1,X2,X3,X4){
; IFDIF<><X1>{PUSH 17,X1↔IFDIF<><X2>{PUSH 17,X2
; IFDIF<><X3>{PUSH 17,X3↔IFDIF<><X4>{PUSH 17,X4}}}}
; PUSHJ 17,NAME}
DEFINE CAT $(A,B){A$B}
;SUBROUTINE DECLARATIONS. MAKES MACROS FOR SYMBOLS REPRESENTING ARGUMENTS
.PLEVEL←←0
.SLEVEL←←0
DEFINE NSUBR(NAME,X1,X2,X3,X4,X5)
{ BEGIN NAME
INTERN NAME
GLOBAL .PLEVEL
GLOBAL .SLEVEL
.SLEVEL←←.SLEVEL+1
CAT(.SBR,→.SLEVEL)←←.PLEVEL
.PLEVEL←←.PLEVEL+1
IFDIF <><X1>{ DEFARG(X1,→.PLEVEL)
.PLEVEL←.PLEVEL+1
IFDIF <><X2>{ DEFARG(X2,→.PLEVEL)
.PLEVEL←.PLEVEL+1
IFDIF <><X3>{ DEFARG(X3,→.PLEVEL)
.PLEVEL←.PLEVEL+1
IFDIF <><X4>{ DEFARG(X4,→.PLEVEL)
.PLEVEL←.PLEVEL+1
IFDIF <><X5>{ DEFARG(X5,→.PLEVEL)
.PLEVEL←.PLEVEL+1
}}}}}
XWD 777000+.PLEVEL-CAT(.SBR,→.SLEVEL)-1,[SIXBIT|NAME|]
↓NAME: ;}
;DEFINE AN ARGUMENT
DEFINE DEFARG(NAME,LEVEL)
{ DEFINE NAME { LEVEL-.PLEVEL(17)}}
;END OF SUBROUTINE
DEFINE SUBREND
{ .PLEVEL←←CAT(.SBR,→.SLEVEL)
.SLEVEL←←.SLEVEL-1
LIT
BLOCK 0
BEND }
;GENERATE SUBROUTINE CALL (DOES THE RIGHT THING WITH SYMBOLIC ARGUEMENTS)
DEFINE CALL(NAME,X1,X2,X3,X4,X5)
{ GLOBAL .SLEVEL,.PLEVEL
.SLEVEL←←.SLEVEL+1
CAT(.SBR,→.SLEVEL)←←.PLEVEL
IFDIF <><X1>{PUSH 17,X1↔.PLEVEL←.PLEVEL+1
IFDIF <><X2>{PUSH 17,X2↔.PLEVEL←.PLEVEL+1
IFDIF <><X3>{PUSH 17,X3↔.PLEVEL←.PLEVEL+1
IFDIF <><X4>{PUSH 17,X4↔.PLEVEL←.PLEVEL+1
IFDIF <><X5>{PUSH 17,X5↔.PLEVEL←.PLEVEL+1
}}}}}
IFDIF <><NAME>{
PUSHJ P,NAME
}
.PLEVEL←←CAT(.SBR,→.SLEVEL)
.SLEVEL←←.SLEVEL-1
}
;PUSH SOMETHING ONTO STACK
DEFINE PUSHP(ARG)
< PUSH P,ARG
.PLEVEL←←.PLEVEL+1
>
DEFINE POPP(ARG)
< POP P,ARG
.PLEVEL←←.PLEVEL-1
>
DEFINE ARG1<-1(17)>↔DEFINE ARG2<-2(17)>
DEFINE ARG3<-3(17)>↔DEFINE ARG4<-4(17)>
DEFINE SETQ(VAR,LIST){CALL(LIST)↔DAC 1,VAR}
;RETURN FROM AN N-ARGUMENT SUBROUTINE CALL.
DEFINE POP0J <POPJ 17,>
↓POP1J.:SUB 17,[2(2)]↔GO@2(17)↔DEFINE POP1J<GO POP1J.>
↓POP2J.:SUB 17,[3(3)]↔GO@3(17)↔DEFINE POP2J<GO POP2J.>
↓POP3J.:SUB 17,[4(4)]↔GO@4(17)↔DEFINE POP3J<GO POP3J.>
↓POP4J.:SUB 17,[5(5)]↔GO@5(17)↔DEFINE POP4J<GO POP4J.>
;ACCUMULATOR AND TEMPORARY DATA MANAGEMENT.
DEFINE ACCUMULATORS(LIST){ACPTR←←2
FOR AC⊂(LIST)<AC←ACPTR↔ACPTR←←ACPTR+1↔>}
DEFINE DECLARE (LIST){
FOR VARNAM⊂(LIST)<VARNAM: 0↔>}
;FATAL ERROR MESSAGE.
DEFINE FATAL(STR){PUSHJ 17,FATAL.↔ASCIZ/STR/}
FATAL.:OUTSTR[BYTE(7)15,12(21)"FAT"↔"AL - "⊗1↔0]
OUTSTR @(17)↔INCHRW↔GO .-1↔LIT
DEFINE CRLF{OUTSTR[BYTE(7)15,12]}
%←←400000
;START ADDRESS ENTRY.
SA: TDCA↔SETA↔DAC RPGFLG↔CALLI ;SET RPG FLAG.
CAR JOBSA↔DAC JOBFF↔CORE↔JFCL ;CORE DOWN LOWER.
LACI =2047↔CORE2↔GO[
FATAL(<CAN'T GET A 2ND SEGMENT.>)]
LAC P,[IOWD PDLLEN,PDL] ;INITIALIZE TABLES
CALL DOCINIT ;INITIALIZE DATA STRUCTURE
;RE-ENTRY ADDRESS.
REE: LACI .↔DAC 124
SKIPE RPGFLG↔JFCL ;RPG INITIALIZATION.
CALL(BEGPROG) ;PROGRAM INITIALIZATION.
;TWO PASS XEROX TEXT ASSEMBLER.
CALL(PASS1)
CALL(PASS2)
;END PROGRAM.
CALLI 0 ;FLUSH LIBRASCOPE.
LAC JOBFF↔CORE↔JFCL ;FLUSH CORE.
SETZ↔CORE2↔JFCL ;FLUSH UPPER SEGMENT.
EXIT
;____________________________________________________________________
SUBR(BEGPROG) ;BEGIN PROGRAM.
BEGIN BEGPROG
LACI 0↔UFBGET↔GO .+3
LACI 1↔UFBGET↔GO[FATAL(<CAN'T GET FASTBANDS.>)]
;DEFAULT INITIALIZE MARGINS.
LAC ROWMIN↔DAC ROW
LACI MROWS-=100↔DAC ROWMAX
LAC LMAR↔DAC LMAR↔DAC COL
LACI NCOLS↔DAC RMAR
;INITIALIZE SCANNER AND CORE ALLOCATION.
SETOM CMODE ;COMMAND MODE.
CALL(MKBUF) ;MAKE XGP BUFFER.
CALL(MKTABL) ;MAKE 2D BIT ADDRESS TABLE.
;DEFINE DEFAULT FONT.
SETZM FONTAB
LAC[XWD FONTAB,FONTAB+1]↔BLT FONTAB+9
LAC[SIXBIT/LPTFNT/]
HLLZM FILNAM↔DIPZ EXTION
LAC FNTPPN↔DAC PPPN
LACI 1↔DAC FONT
CALL(<DEFONT+1>)
;RESCAN COMMAND LINE FOR CHARACTERS RIGHT OF SEMI-COLON.
RESCAN↔INCHSL↔EXIT↔CAIN 15↔EXIT
CAIE";"↔GO .-5↔DZM CHRCNT
CDR JOBFF↔LIPI 440700
DAC TXTPTR↔DAC TXTORG
INCHSL 1↔EXIT
CAIN 1,"D"↔SETOM BUGFLG↔GO .+3
INCHSL 1↔GO .+4↔AOS CHRCNT
IDPB 1,0↔GO .-4↔DAC TXTEND
SKIPN BUGFLG↔POP0J
;; OUTSTR[ASCIZ/BEGIN./]↔INCHRW↔CRLF
POP0J
BEND BEGPROG;________________________________________________________
SUBR(PASS1)
BEGIN PASS1
LAC TXTORG↔DAC TXTPTR
CDR 1,TXTEND↔CDR 0,TXTORG
SUB 1,0↔AOS 1↔IMULI 1,5↔DAC 1,CHRCNT
L1: SETQ(CHAR,{GETCHR})
SKIPGE CHRCNT↔GO L3
SKIPE CMODE↔GO L2
;TEXT MODE CHARACTER.
CAR A00(1)
CAIN 1,"~"↔SETOM CMODE
; SKIPE↔PUSHJ P,@0
GO L1
;COMMAND MODE CHARACTER.
L2: CDR A00(1)
CAIN 1,"F"↔GO[CALL(GETCHR)↔SETZM CMODE↔GO L1]
CAIN 1,"@"↔PUSHJ P,@0
GO L1
;END OF DOCUMENT.
L3: SETOM CMODE
POP0J
BEND PASS1;__________________________________________________________
SUBR(PASS2)
BEGIN PASS2
;START-OF-DOCUMENT.
LAC TXTORG↔DAC TXTPG#↔DZM EOF
CDR 1,TXTEND↔CDR 0,TXTORG
SUB 1,0↔AOS 1↔IMULI 1,5↔DAC 1,CHRCNT
LAC CHRCNT↔DAC SAVCNT#↔SETZM SAVTPC
;START-OF-PAGE.
L0: LACI =511↔DAC QHI↔DZM QLO↔DZM QPAGE ;1ST QUARTER PAGE.
L00: LAC TXTPG↔DAC TXTPTR ;TOP-OF-THE-PAGE.
LAC SAVTPC↔DAC TEXTPC
LAC SAVCNT↔DAC CHRCNT
LAC ROWMIN↔DAC ROW
;START-OF-QUARTER-PAGE.
LAC ORGXGP↔DZM@↔DIP↔AOS↔BLT@ENDXGP ;CLEAR QUARTER PAGE.
LAC [SIXBIT/TEXT/]↔DAC ANAME ;SET DEFAULT AREA
CALL(NXTPAGE)
SETZM TJODEPTH
SETZM TJPTR
SKIPN BUGFLG↔GO L1
; OUTSTR[ASCIZ/QUARTER /]
; LAC QPAGE↔IORI"0"↔OUTCHR↔CRLF
;PROCESS A CHARACTER.
L1: SETQ(CHAR,{GETCHR})
SKIPGE CHRCNT↔GO L3 ;END OF DOCUMENT.
JUMPE 1,L1
CAIN 1,14↔GO L3 ;FORM FEED.
SKIPE CMODE↔GO L2
CAIN 1,"~"↔GO [ SETOM CMODE↔GO L1 ]
CALL TEXT↔GO L1 ;TEXT MODE CHARACTER.
L2: CDR A00(1) ;COMMAND MODE CHARACTER.
SKIPE↔PUSHJ P,@0↔GO L1
;WRITE QUARTER-PAGE ON FAST BAND.
L3: LAC 1,QPAGE
LAC[0↔=784↔=1568↔0](1)↔DAC SECTOR
LAC ORGXGP↔DAC BUFPTR
LACI =25088↔DAC WRDCNT
LAC[0↔0↔0↔1](1)↔DAC BAND
FBWRT BUFPTR↔OUTSTR[ASCIZ/WARNING: FB WRITE ERROR./]
;ADVANCE TO NEXT QUARTER PAGE.
LACI =512↔ADDM QLO↔ADDM QHI
AOS 1,QPAGE↔CAIGE 1,4↔GO L00
;ADVANCE TO NEXT PAGE.
L4: CALL(XGPOUT)
SETOM 0↔TTYUUO 6,0↔CAIN 0,-1↔GO L4A
OUTSTR[ASCIZ/IS THIS PAGE OK ?/]↔INCHRW↔CAIN"N"↔GO L4
L4A: CRLF
LAC TXTPTR↔DAC TXTPG
LAC CHRCNT↔DAC SAVCNT
LAC TEXTPC↔DAC SAVTPC
SKIPN EOF↔GO L0
POP0J
BEND PASS2;__________________________________________________________
HTAB: LAC COL↔SUB LMAR ;TEXT HORIZONTAL TAB.
LAC 16,DCOL↔SUBI 16,2 ;KLUDGE TO MAKE CRE DOCUMENT.
IDIV 16↔ANDCMI 7
ADDI 8↔IMUL 16↔ADD LMAR
DAC COL
POP0J
CRETURN:LAC LMAR ;TEXT CARRIAGE RETURN.
DAC COL
POP0J
LFEED: LAC DROW ;TEXT LINE FEED.
ADDM ROW
GO ROWCHK
SPACE: LAC DCOL↔ADDM COL
↑COLCHK:LAC COL↔CAMG RMAR↔GO ROWCHK ;COLUMN OVERFLOW - DEFAULT CRLF.
LAC LMAR↔DAC COL
LAC DROW↔ADDM ROW
↑ROWCHK:LAC ROW↔CAMGE ROWMAX↔POP0J ;ROW OVERFLOW - Fetch next window
CALL NXTWINDOW↔POP0J
FFEED: SKIPA↔CALL(XGPOUT) ;FORM FEED.
LAC ROWMIN↔DAC ROW
LAC LMAR↔DAC COL↔POP0J
ESCAPE: SETOM CMODE↔POP0J
SUBR(MKTABL) ;MAKE 2D BIT ADDRESSING TABLE IN 2ND SEGMENT.
;TWO DIMENSION BIT ADDRESSING.
DEFINE DOT(R,C){HLLZ 1,%(C)↔ROT 1,6↔HRRI 1,@%(R)↔DPB 0,1}
COMMENT ⊗
The DOT macro places a bit at a given row and column of the
XGP buffer. The 2D bit address byte pointer is computed by twice
referencing a 2K table in which the Nth word contains the bytes
0:5(N div =36) 6:11(N mod =36) 12:17(01) 18:35(orgXGP+N*WWIDTH).
That is the left halfword of the Nth table entry contains the base
address of the Nth row; and the right halfword of the Nth table
entry contains a byte pointer to the Nth column. In the DOT macro,
the HLLZ and ROT instructions setup the column byte pointer and the
HRRI instruction (thru the magic of immediate indirect double
indexing) adds the right halfword of the Nth row table entry to the
byte pointer. The use of accumulator 1 is mandatory because of the
index-byte-size pun. The following subroutine initializes the table.⊗
BEGIN MKTABL;________________________________________________________
LAC[XWD L,1]↔BLT 11
LAC ORGXGP↔AOS↔TLO 4301↔PUSHJ P,3
LAP ORGXGP↔AOS↔LIPI 2,-=512↔PUSHJ P,3
LAP ORGXGP↔AOS↔LIPI 2,-=512↔PUSHJ P,3
LAP ORGXGP↔AOS↔LIPI 2,-=512↔GO 3
L: XWD -100,WWIDTH ;1 INCREMENT.
XWD -=512,% ;2 AOBJN TABLE POINTER.
DAC 0,(2) ;3
TLNN 0,7700 ;4 TEST FOR =36 OVERFLOW.
ADD 0,[144B11] ;5 INCREMENT COLUMN WORD COUNT.
ADD 0,1 ;6
AOBJN 2,3 ;7
POP0J ;8
BEND MKTABL;BGB 24 MAY 1973._________________________________________
SUBR(MKBUF) MAKE XGP BUFFER (ONE PHASE) 512 ROWS.
BEGIN MKBUF;------------------------------------------------------
;EXPAND CORE FOR XGP BUFFER.
CDR JOBFF↔DAC ORGXGP
ADDI BUFSIZ-1↔DAC ENDXGP
ADDI 3*WWIDTH+10↔DAC JOBFF↔ADDI =3000
CORE↔GO[FATAL(CAN'T GET CORE FOR XGP BUFFER)]
;CLEAR XGP BUFFER.
LAC 1,ORGXGP↔SETZM(1)
DIP 1,1↔AOS 1↔BLT 1,@JOBREL
POP0J
BEND MKBUF;BGB 27 JANUARY 1973.-----------------------------------
SUBR(XGPOUT) OUTPUT BUFFER TO XGP FROM SECONDARY STORAGE.
BEGIN XGPOUT;-----------------------------------------------------
BSIZ ←← =6272 ↔ BCNT ←← =16 ;BUFFER SIZE & NUMBER OF THEM.
SETZ 1,↔SEGNUM 1,↔DAC 1,MYSEG#↔DETSEG↔;LOCK;DETACH SEGMENT.
OUTSTR[ASCIZ/PAGE TO XGP.../]
LAC ORGXGP↔DAC BUFORG↔ADDI 3*BSIZ↔DAC BUFEND
CAMLE JOBREL↔CORE↔JFCL
DZM BAND↔DZM SECTOR↔LAC BUFORG↔DAC BUFPTR
;XGP OUTPUT ONE PAGE.
INIT 2,117↔SIXBIT/XGP/↔0↔GO[OUTSTR[ASCIZ/XGP INIT FAILED.
/]↔ POP0J]↔LOCK↔LACI 3,BCNT ;THIS MANY DRUM BUFFERS PER PAGE.
;READ DRUM.
L1: LACI BSIZ↔DAC WRDCNT↔LAC BAND
FBREAD BUFPTR↔OUTSTR[ASCIZ/FAST BAND READ ERROR. /]
LACI =196↔ADDB SECTOR↔CAIG =2156↔GO .+3↔DZM SECTOR↔AOS BAND
;PUT XGP CONTROL WORD IN EACH ROW.
LAC[1B11+=48]↔LAC 1,BUFPTR↔LACI 2,=128
DAC(1)↔ADDI 1,=49↔SOJG 2,.-2
CAIE 3,BCNT↔GO L2
OUT 2,CUTARG↔SKIPA↔JFCL
;PRINT ON XGP.
L2: SLACI -BSIZ↔LAP BUFPTR↔SOS↔ASH 3,1↔DAC DUMARG(3)
OUT 2,DUMARG(3)↔SKIPA↔OUTSTR[ASCIZ/XGP ERROR /]↔ASH 3,-1
CAIE 3,1↔GO L3
OUT 2,CUTARG↔SKIPA↔JFCL↔GO L4
;ADVANCE TO NEXT BUFFER.
L3: LACI BSIZ↔ADDB BUFPTR↔CAMGE BUFEND↔GO L4
LAC BUFORG↔DAC BUFPTR
L4: SOJG 3,L1↔UNLOCK↔RELEASE 2,↔OUTSTR[ASCIZ/FINISHED./]↔CRLF
LAC 1,MYSEG↔JUMPE 1,.+3 ;RE-ATTACH SEGMENT.
ATTSEG 1,↔GO[OUTSTR[ASCIZ/ATTSEG FAILED. /]↔HALT .+1]
POP0J
;____________________________________________________________________
BUFORG:0↔BUFEND:0 ;XGP BUFFERS.
CUTARG: IOWD 2,HACK↔0
DUMARG:BLOCK BSIZ*2 + 4
HACK: 1B0+=30B11↔0 ;CHOP PAPER.
BEND XGPOUT;BGB 28 MAY 1973.--------------------------------------
BAND:0↔BUFPTR:0↔WRDCNT:=12544↔SECTOR:0 ;FB UUO ARGUMENT.
SUBR(PRINT) PLACE A GLYPH INTO XGP BUFFER AT ROW,COL.
BEGIN PRINT;------------------------------------------------------
ACCUMULATORS{G,B,B2,M,N,I,X16}
LAC 1,FONT ;CURRENT FONT NUMBER.
SKIPN 2,FONTAB(1)↔POP0J ;FONT BASE ADDRESS.
LAC I,203(2) ;ROWS BETWEEN TOP AND BASE LINE.
ADD 2,CHAR ;POINTER INTO FONT'S CHARACTER TABLE.
CAR N,(2) ;COLS WIDE OF THE GLYPH.
CDR G,(2)↔SKIPN G↔POP0J ;EXIT WHEN NO CHARACTER.
ADD G,FONTAB(1)↔AOS G ;CHARACTER'S GLYPH POINTER.
CDR M,(G) ;ROWS HIGH OF THE GLYPH.
CAR 0,(G) ;ROWS FROM TOP TO FIRST ROW OF GLYPH.
SUB 0,I ;ROWS ABOVE CURRENT XGP PEN POSITION.
ADD 0,ROW↔SUB 0,QLO
IMULI WWIDTH
ADD ORGXGP↔DAPZ B ;WORD POINTER INTO XGP BUFFER.
LAC 0,COL
SKIPE TJMODE↔GO .+3 ;CLIP LINE OVERFLOW IF TJMODE=0
CAML 0,RMAR↔POP0J
IDIVI 0,=36 ;REMAINDER IN AC-1 !
AOS↔ADD B,0↔DAC B,B2 ;WORD POINTER INTO XGP BUFFER.
LAC X16,FONT↔CAIN X16,8 ;SPECIAL HACK FOR CRE MANUAL.
GO[LAC X16,DCOL↔SUBI X16,2↔ADDM X16,COL↔GO .+2]
ADDM N,COL ;UPDATE XGP PEN COLUMN POSITION.
TLO G,444400↔AOS G ;SETUP GLYPH BYTE POINTER.
CAILE N,=36↔GO[
IDIVI N,=36↔AOJA N,L0] ;WHEN CHARACTER WIDTH ≥ =36.
DPB N,[POINT 6,G,11] ;SIZE OF BYTE.
ADD 1,N↔SUBI 1,=36 ; =36 - CHRWID - REMAINDER
LACI N,1
L0: MOVNS 1↔DAP 1,L3 ;BYTE POSITION WITH RESPECT TO WORD BOUNDARYS.
;INCLUSIVE OR GLYPH BITS INTO THE XGP BUFFER.
L1: LAC I,N
L2: ILDB 0,G↔SETZ 1,
L3: LSHC 0,0
CAML B,ORGXGP↔CAMLE B,ENDXGP↔SKIPA↔IORM 0,(B)
AOS B↔JUMPE 1,L4
CAML B,ORGXGP↔CAMLE B,ENDXGP↔SKIPA↔IORM 1,(B)
L4: SOJG I,L2↔LAC B,B2
ADDI B,WWIDTH↔DAC B,B2
SOJG M,L1
POP0J
BEND PRINT;BGB 23 MAY 1973.---------------------------------------
SUBR TEXT
BEGIN TEXT
LAC 1,CHAR
SKIPE TEXTPC
GO @TEXTPC ;Co-routine linkage!
GO NEWPAR
$GETCH: POP P,TEXTPC ;Where to continue co-routine
POP0J ;TEXT is called with a PUSHJ
;Begin a paragraph
NEWPAR: SETOM CRFLAG
CALL LBFLUSH ;Flush any existing text
GO CR3
NXTCHR: CALL $GETCH ;Get a character
GOTCHR: CAR 0,A00(1) ;Special?
JUMPN 0,SPCHAR
PUTCHR: SKIPE TJPTR ;Is line buffer set up?
GO PTROK ;Yes
LAC 0,[POINT 7,LINBUF]
DAC 0,TJPTR ;Setup pointer to end of pointer
SETZM TJHEIGHT ;Clear maximum height for row
SETZM TJDEPTH ;Clear maximum depth for row
LACI 0,5*LINLEN ;Setup character count
DAC 0,TJCNT
LAC 0,COL
DAC 0,TJLMAR ;Left margin for text justification.
LAC 0,RMAR
DAC 0,TJRMAR ;Right margin for text justification,
SETOM TJFONT ;Force initial font select
PTROK: SKIPN TJMODE ;If not clip mode
GO COLOK
LAC 0,COL ;Check column overflow
CAMGE 0,TJRMAR
GO COLOK ;OK
CALL LBLINE ;Put out line
SETOM LFFLAG ;Set flag for line feed
COLOK: LAC 2,FONT ;Check for font change
CAMN 2,TJFONT
GO FONTOK
CAIL 2,20
GO [ FATAL(FONT NUMBER > 15.) ]
LACI 2,177 ;Save number of font
IDPB 2,TJPTR
SOSG TJCNT
CALL LBLOSE
LAC 2,FONT
DAC 2,TJFONT
IDPB 2,TJPTR
SOSG TJCNT
CALL LBLOSE
SKIPN 2,FONTAB(2) ;Make sure the font exists!
CALL NOFONT
LAC 0,203(2) ;Check height
CAMLE 0,TJHEIGHT
DAC 0,TJHEIGHT
LAC 0,201(2) ;Check depth
SUB 0,203(2)
CAMLE 0,TJDEPTH
DAC 0,TJDEPTH
FONTOK: IDPB 1,TJPTR ;Put character into buffer
SOSG TJCNT
CALL LBLOSE
PUSH P,[NXTCHR] ;Fake a return address!
ADVCOL: LAC 2,FONT
SKIPN 2,FONTAB(2) ;Fetch address of font
CALL NOFONT ;Font not there!
ADD 2,1 ;Update column
CAR 0,(2)
ADDM 0,COL
POP0J
;Special characters
SPCHAR: CAIN 1," "
GO [ CALL PUTCHR ;Put space into line buffer
SKIPG TJMODE ;Are we justifying?
GO NXTCHR ;No, just get next character
CALL $GETCH ;Get another character
CAIN 1," " ;Flush multiple spaces (is this really
GO $.-2 ;a good idea?)
GO GOTCHR ] ;Put character into buffer
CAIN 1,15 ;<RETURN>?
GO [ SKIPG TJMODE ;Are we justifying?
GO [ SETOM CRFLAG
CALL LBFLUSH ;No, flush current line
GO NXTCHR ]
CALL $GETCH ;[Justify mode] Get another character
CAIE 1,12 ;Bare <RETURN>?
GO CR3
CALL $GETCH ;Test for start of paragraph
CAR 0,A00(1) ;Special?
JUMPE 0,[ PUSH P,1 ;Save printing character
LACI 1," " ;Stuff space instead of return
CALL PUTCHR ;Put into buffer
POP P,1 ;Now do printer character
GO PUTCHR ]
CAIE 1,15
CAIN 1,12
GO [ CALL LBFLUSH
SETOM LFFLAG
GO NEWPAR ]
CAIN 1,11
GO [ TAB1: CAR 0,A00(1)
CALL @0
LAC 0,COL
DAC 0,TJLMAR
CALL $GETCH
CAIN 1,11
GO TAB1
GO GOTCHR ]
CAIN 1," "
GO [ SETOM CRFLAG
CALL LBFLUSH
SETOM LFFLAG
CR2: CAR 0,A00(1)
CAIN 1," "
GO CR4
CALL @0
CALL $GETCH
CR3: CAIN 1,15
GO CR2
CAIN 1,11
GO [ SETZM TJPTR
GO TAB1 ]
CAIE 1," "
GO GOTCHR
CR4: CALL PUTCHR
CALL $GETCH
GO CR3 ]
CAIE 1,14
CAIN 1,13
GO [ CALL LBFLUSH
CALL @0
SETOM LFFLAG
GO NEWPAR ]
CALL @0
GO NXTCHR
GO PUTCHR ]
CAIN 1,12
GO [ CALL LBFLUSH
SETOM LFFLAG
GO NXTCHR ]
CAIE 1,13
CAIN 1,14
GO [ CALL LBFLUSH
CALL @0
SETOM LFFLAG
GO NEWPAR ]
CAIN 1,11
GO [ CALL LBFLUSH
CAR 0,A00(1)
CALL @0
LAC 0,COL
DAC 0,TJLMAR
GO NXTCHR ]
CALL @0
GO NXTCHR
GO PUTCHR
LBLOSE: FATAL(LINE JUSTIFYING BUFFER FULL!)
DECLARE{↑TEXTPC}
BEND TEXT
SUBR LBLINE
BEGIN LBLINE
PTR←←16
MODE←←15
EXTRA←←14
PUSH P,1
PUSH P,EXTRA
PUSH P,PTR
PUSH P,MODE
PUSH P,CHAR
PUSH P,FONT
LAC MODE,TJMODE
LAC PTR,[POINT 7,LINBUF]
SETZM SPFLAG
SKIPN LFFLAG
GO LFOK
SETZM LFFLAG
LAC 1,TJDEPTH
CAMGE 1,TJODEPTH
LAC 1,TJODEPTH
ADD 1,TJHEIGTH
ADD 1,XLINE
ADDM 1,ROW
CALL ROWCHK
LFOK: SKIPE TJPTR
CAMN PTR,TJPTR
GO RET
SETOM TJSCNT ;Clear space count
SETZM TJSPOS ;Clear column of space
FNDSPA: CAMN PTR,TJPTR
GO [ LAC COL
DAC TJSPOS
GO GOTSPA ]
GOTSPA: DAC PTR,TJSPTR
LAC PTR,[POINT 7,LINBUF]
LAC EXTRA,TJRMAR
SUB EXTRA,TJSPOS
LAC 1,TJLMAR
EXCH 1,COL
CAMGE 1,TJRMAR
GO [ CAIN MODE,$BOTH
LAC MODE,$LEFT
GO .+1 ]
SETOM CRFLAG
LAC 1,TJPTR ;CLIP and AUTO use TJPTR instead of TJSPTR
SKIPE TJSPTR
CAIG MODE,$CLIP
DAC 1,TJSPTR
CAIN MODE,$CENTER
ASH EXTRA,-1
CAIE MODE,$RIGHT
CAIN MODE,$CENTER
ADDM EXTRA,COL
LOOP1: CAMN PTR,TJSPTR
GO LINDON
ILDB 1,PTR
CAIN 1,177
GO [ ILDB 1,PTR
CAIN 1,177
GO .+1
CAIL 1,20
GO [ FATAL(FONT NUMBER > 15.) ]
DAC 1,FONT
GO LOOP1 ]
CAIN 1," "
CAIE MODE,$BOTH
GO [ DAC 1,CHAR
CALL PRINT
GO LOOP1]
LAC 0,EXTRA
IDIV 0,TJSCNT
SOSGE TJSCNT
GO [ FATAL(SPACE COUNT SCREWED UP) ]
SUB EXTRA,0
LAC 1,FONT
SKIPN 1,FONTAB(1)
CALL NOFONT
CAR 1," "(1)
ADD 1,0
ADDM 1,COL
GO LOOP1
LINDON: LACI 1,5*LINLEN-2
DAC 1,TJCNT
LAC 1,COL
JUMPL MODE,LINDO2
CAMLE 1,TJRMAR
GO [ FATAL(COLUMN COUNT SCREWED UP!) ]
CAMN 1,TJRMAR
GO LINDO2
CAIE MODE,$BOTH
CAIN MODE,$RIGHT
GO [ FATAL(JUSTIFY LOST) ]
LINDO2: SKIPN CRFLAG
GO LINDO3
SETZM CRFLAG
LAC 1,LMAR
DAC 1,TJLMAR
DAC 1,COL
LINDO3: CAMN PTR,TJPTR
GO EMPTY
LAC EXTRA,PTR
LAC PTR,[POINT 7,LINBUF,6]
LAC 1,FONT
IDPB 1,PTR
SOS TJCNT
JUMPLE MODE,LOOP2
ILDB 1,EXTRA
CAIE 1," "
ADD EXTRA,[7B5] ;Decrement byte pointer!
LOOP2: CAMN EXTRA,TJPTR
GO MOVDON
ILDB 1,EXTRA
IDPB 1,PTR
SOS TJCNT
CAIE 1,177
GO CONT2
CAMN EXTRA,TJPTR
HALT .
ILDB 1,EXTRA
IDPB 1,PTR
SOS TJCNT
CAIN 1,177
GO CONT2
DAC 1,FONT
GO LOOP2
CONT2: LAC 2,FONT
SKIPN 2,FONTAB(2)
CALL NOFONT
ADD 2,1
CAR 2,(2)
ADDM 2,COL
GO LOOP2
EMPTY: LAC PTR,[POINT 7,LINBUF]
SETOM TJFONT
MOVDON: SETZM TJSPTR
SETOM TJSCNT
SETZM TJSPOS
DAC PTR,TJPTR
RET: POP P,FONT
POP P,CHAR
POP P,MODE
POP P,PTR
POP P,EXTRA
POP P,1
POP0J
DECLARE{SPFLAG}
BEND LBLINE
NOFONT: FATAL(NO FONT DEFINED)
LBFLUSH:LAC 0,COL
SKIPE TJMODE ;AUTO CLIP ALWAYS DOES ONE OUTPUT
CAMG 0,TJRMAR
GO [ LAC 0,TJMODE
CAIN 0,$BOTH
GO [ PUSH P,TJRMAR
LAC 0,COL
DAC 0,TJRMAR
CALL LBLINE
POP P,TJRMAR
SETOM LFFLAG
POP0J ]
GO LBLINE ]
CALL LBLINE
SETOM LFFLAG
GO LBFLUSH